using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Windows;
namespace Microsoft.Expression.Drawing.Core
{
	internal static class CommonExtensions
	{
		public static void ForEach(this IEnumerable items, Action<object> action)
		{
			IEnumerator enumerator = items.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					object current = enumerator.get_Current();
					action.Invoke(current);
				}
			}
			finally
			{
				IDisposable disposable = enumerator as IDisposable;
				if (disposable != null)
				{
					disposable.Dispose();
				}
			}
		}
		public static void ForEach<T>(this IEnumerable<T> items, Action<T> action)
		{
			using (IEnumerator<T> enumerator = items.GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
					T current = enumerator.get_Current();
					action.Invoke(current);
				}
			}
		}
		public static void ForEach<T>(this IList<T> list, Action<T, int> action)
		{
			for (int i = 0; i < list.get_Count(); i++)
			{
				action.Invoke(list.get_Item(i), i);
			}
		}
		public static bool EnsureListCount<T>(this IList<T> list, int count, Func<T> factory = null)
		{
			if (list == null)
			{
				throw new ArgumentNullException("list");
			}
			if (count < 0)
			{
				throw new ArgumentOutOfRangeException("count");
			}
			if (list.EnsureListCountAtLeast(count, factory))
			{
				return true;
			}
			if (list.get_Count() > count)
			{
				List<T> list2 = list as List<T>;
				if (list2 != null)
				{
					list2.RemoveRange(count, list.get_Count() - count);
				}
				else
				{
					for (int i = list.get_Count() - 1; i >= count; i--)
					{
						list.RemoveAt(i);
					}
				}
				return true;
			}
			return false;
		}
		public static bool EnsureListCountAtLeast<T>(this IList<T> list, int count, Func<T> factory = null)
		{
			if (list == null)
			{
				throw new ArgumentNullException("list");
			}
			if (count < 0)
			{
				throw new ArgumentOutOfRangeException("count");
			}
			if (list.get_Count() < count)
			{
				List<T> list2 = list as List<T>;
				if (list2 != null && factory == null)
				{
					list2.AddRange(new T[count - list.get_Count()]);
				}
				else
				{
					for (int i = list.get_Count(); i < count; i++)
					{
						list.Add((factory == null) ? default(T) : factory.Invoke());
					}
				}
				return true;
			}
			return false;
		}
		public static void AddRange<T>(this ICollection<T> collection, IEnumerable<T> newItems)
		{
			if (collection == null)
			{
				throw new ArgumentNullException("collection");
			}
			List<T> list = collection as List<T>;
			if (list != null)
			{
				list.AddRange(newItems);
				return;
			}
			using (IEnumerator<T> enumerator = newItems.GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
					T current = enumerator.get_Current();
					collection.Add(current);
				}
			}
		}
		public static T Last<T>(this IList<T> list)
		{
			return list.get_Item(list.get_Count() - 1);
		}
		public static void RemoveLast<T>(this IList<T> list)
		{
			list.RemoveAt(list.get_Count() - 1);
		}
		internal static T DeepCopy<T>(this T obj) where T : class
		{
			if (obj == null)
			{
				return default(T);
			}
			Type type = obj.GetType();
			if (!type.get_IsValueType())
			{
				if (type != typeof(string))
				{
					if (typeof(IList).IsAssignableFrom(type))
					{
						IList collection = (IList)Activator.CreateInstance(type);
						((IList)((object)obj)).ForEach(delegate(object o)
						{
							collection.Add(o.DeepCopy<object>());
						});
						return (T)((object)collection);
					}
					if (type.get_IsClass())
					{
						object obj2 = Activator.CreateInstance(obj.GetType());
						PropertyInfo[] properties = type.GetProperties(20);
						PropertyInfo[] array = properties;
						for (int i = 0; i < array.Length; i++)
						{
							PropertyInfo propertyInfo = array[i];
							if (propertyInfo.get_CanRead() && propertyInfo.get_CanWrite())
							{
								object value = propertyInfo.GetValue(obj, null);
								object value2 = propertyInfo.GetValue(obj2, null);
								if (value != value2)
								{
									propertyInfo.SetValue(obj2, value.DeepCopy<object>(), null);
								}
							}
						}
						return (T)((object)obj2);
					}
					throw new NotImplementedException();
				}
			}
			return obj;
		}
		public static bool SetIfDifferent(this DependencyObject dependencyObject, DependencyProperty dependencyProperty, object value)
		{
			object value2 = dependencyObject.GetValue(dependencyProperty);
			if (!object.Equals(value2, value))
			{
				dependencyObject.SetValue(dependencyProperty, value);
				return true;
			}
			return false;
		}
		public static bool ClearIfSet(this DependencyObject dependencyObject, DependencyProperty dependencyProperty)
		{
			object obj = dependencyObject.ReadLocalValue(dependencyProperty);
			if (obj != DependencyProperty.UnsetValue)
			{
				dependencyObject.ClearValue(dependencyProperty);
				return true;
			}
			return false;
		}
		public static IEnumerable<T> FindVisualDesendent<T>(this DependencyObject parent, Func<T, bool> condition) where T : DependencyObject
		{
			CommonExtensions.<FindVisualDesendent>d__8<T> <FindVisualDesendent>d__ = new CommonExtensions.<FindVisualDesendent>d__8<T>(-2);
			<FindVisualDesendent>d__.<>3__parent = parent;
			<FindVisualDesendent>d__.<>3__condition = condition;
			return <FindVisualDesendent>d__;
		}
		public static IEnumerable<DependencyObject> GetVisualChildren(this DependencyObject parent)
		{
			CommonExtensions.<GetVisualChildren>d__d <GetVisualChildren>d__d = new CommonExtensions.<GetVisualChildren>d__d(-2);
			<GetVisualChildren>d__d.<>3__parent = parent;
			return <GetVisualChildren>d__d;
		}
	}
}
